import {
  center,
  circle,
  distance,
  pointsWithinPolygon,
  polygon,
} from '@turf/turf';
import type { LngLatLike } from 'mapbox-gl';

export type PaintMode =
  | 'select'
  | 'circle'
  | 'rectangle'
  | 'freedom'
  | 'circle-radius';

// TODO 单独开一个文件夹并将当前paint改为select，
// 抽象一个不同于draw的基础paint，至于是select还是什么逻辑由上层决定

export type Paint = {
  id?: string;
  type: 'circle' | 'rectangle' | 'freedom' | 'circle-radius';
  coordinates: [number, number][];
  selected?: boolean;
};

/**
 * @param ptn [number, number]
 * @description GeoJSON.FeatureCollection<GeoJSON.Point>
 */
export function point2Feature(ptn: [number, number]) {
  return {
    type: 'Feature',
    geometry: { type: 'Point', coordinates: [ptn[0], ptn[1]] },
    properties: {},
  } as GeoJSON.Feature<GeoJSON.Point>;
}

export function getPolygon(paint: Paint) {
  if (paint.type === 'circle') {
    const cc = [
      (paint.coordinates[0][0] + paint.coordinates[1][0]) / 2,
      (paint.coordinates[0][1] + paint.coordinates[1][1]) / 2,
    ];
    const radius = distance(cc, paint.coordinates[1]);
    return circle(cc, radius);
  }
  if (paint.type === 'rectangle') {
    const p0 = paint.coordinates[0];
    const p2 = paint.coordinates[1];
    const p1 = [p2[0], p0[1]];
    const p3 = [p0[0], p2[1]];
    return polygon([[p0, p1, p2, p3, p0]]);
  }
  if (paint.type === 'freedom') {
    const coords = [...paint.coordinates];
    if (coords.length < 3) return undefined;
    coords.push(coords[0]);
    return {
      type: 'Feature',
      geometry: {
        // type: 'LineString',
        // coordinates: paint.coordinates,
        type: 'Polygon',
        coordinates: [coords],
      },
      properties: {},
    } as GeoJSON.Feature<GeoJSON.Polygon>;
  }
  if (paint.type === 'circle-radius') {
    const cc = paint.coordinates[0];
    const radius = distance(cc, paint.coordinates[1]);
    return circle(cc, radius);
  }
}

export function calculateObjectsInPolygon<
  T extends { longitude: number; latitude: number },
>(objects: T[] | undefined, paint: Paint): T[] | undefined {
  if (!objects) return undefined;
  const points = {
    type: 'FeatureCollection',
    features: objects.map((obj) => ({
      type: 'Feature',
      geometry: {
        type: 'Point',
        coordinates: [obj.longitude, obj.latitude],
      },
      properties: { originalObject: obj },
    })),
  } as GeoJSON.FeatureCollection<GeoJSON.Point>;
  const poly = getPolygon(paint);
  const pointsWithin = poly ? pointsWithinPolygon(points, poly) : null;
  return pointsWithin?.features.map((f) => f.properties?.originalObject as T);
}

export function getPaintCenter(paint: Paint): LngLatLike | undefined {
  if (!paint) return undefined;
  const feature = getPolygon(paint);
  if (!feature) return undefined;
  const cg = center(feature);
  return [cg.geometry.coordinates[0], cg.geometry.coordinates[1]];
}

// TODO 考虑是否需要处理circle-radius，circle,多余的处理
export function getPaintCenterNRadius(paint: Paint) {
  if (!paint) return undefined;
  const feature = getPolygon(paint);
  if (!feature) return undefined;
  const cg = center(feature);
  return {
    center: [cg.geometry.coordinates[0], cg.geometry.coordinates[1]],
    radius: distance(cg, paint.coordinates[1]),
  };
}
